package com.gitee.ixtf.vertx.internal

import com.gitee.ixtf.vertx.Subscription
import graphql.schema.DataFetcher
import java.lang.reflect.Method
import java.lang.reflect.Parameter
import org.eclipse.microprofile.graphql.Mutation
import org.eclipse.microprofile.graphql.Query
import org.eclipse.microprofile.graphql.Source

class MutationMethod(method: Method) : GraphqlMethod(method) {
  override val typeName by lazy { "Mutation" }
  private val annotation by lazy { method.getAnnotation(Mutation::class.java) }
  override val fieldName: String by lazy { annotation.run { value.ifBlank { method.name } } }
  override val dataFetcher: DataFetcher<*> by lazy {
    if (isSuspend) SuspendMutationDataFetcher(this) else DefaultMutationDataFetcher(this)
  }
}

class QueryMethod(method: Method) : GraphqlMethod(method) {
  override val typeName by lazy { "Query" }
  private val annotation by lazy { method.getAnnotation(Query::class.java) }
  override val fieldName: String by lazy { annotation.run { value.ifBlank { method.name } } }
  override val dataFetcher: DataFetcher<*> by lazy {
    if (isSuspend) SuspendQueryDataFetcher(this) else DefaultQueryDataFetcher(this)
  }
}

class SubscriptionMethod(method: Method) : GraphqlMethod(method) {
  override val typeName by lazy { "Subscription" }
  private val annotation by lazy { method.getAnnotation(Subscription::class.java) }
  override val fieldName: String by lazy { annotation.run { value.ifBlank { method.name } } }
  override val dataFetcher: DataFetcher<*> by lazy {
    if (isSuspend) SuspendSubscriptionDataFetcher(this) else DefaultSubscriptionDataFetcher(this)
  }
}

class SourceMethod(method: Method, parameter: Parameter) : GraphqlMethod(method) {
  override val typeName: String by lazy { parameter.type.simpleName }
  private val annotation by lazy { parameter.getAnnotation(Source::class.java) }
  override val fieldName: String by lazy { annotation.run { name.ifBlank { method.name } } }
  override val dataFetcher: DataFetcher<*> by lazy {
    if (isSuspend) SuspendSourceDataFetcher(this) else DefaultSourceDataFetcher(this)
  }
}
